package com.zhu.rpc.client.handler;

import com.zhu.rpc.MsgType;
import com.zhu.rpc.client.RpcClient;
import com.zhu.rpc.client.RpcRequest;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.EventLoop;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.CharsetUtil;
import io.netty.util.Timer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ClientHeartBeatHandler extends ChannelInboundHandlerAdapter {
    Future future;
    private static final ByteBuf HEARTBEAT_SEQUENCE = Unpooled.unreleasableBuffer(Unpooled.copiedBuffer("10",
            CharsetUtil.UTF_8));
    private Logger logger = LoggerFactory.getLogger(ClientHeartBeatHandler.class);
    private String serverName;
    private String host;
    private int port;
    public ClientHeartBeatHandler(String serverName,String host,int port) {
        this.serverName = serverName;
        this.port = port;
        this.host = host;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        logger.debug("{}连接成功了",serverName);
        super.channelActive(ctx);
    }

    //TODO 创建一个固定的定时任务线程池来处理这个定时任务 重连任务可以适当的设置让重连的间隔时间越来越长？？
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        logger.debug("{}掉线了？？？",serverName);
        ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);

        future = executorService.scheduleAtFixedRate(()->{
            try {
                logger.debug("{}正在重新连接。。。",serverName);
                ChannelFuture channelFuture = new RpcClient().connect(port,host,serverName).sync();
                RpcRequest.setNettyChannel(serverName,channelFuture.channel());
                future.cancel(true);
//                executorService.shutdown();
            } catch (Exception e) {
                logger.debug("{}重新连接失败",serverName);

            }

        },1L,3L,TimeUnit.SECONDS);

    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        super.userEventTriggered(ctx, evt);
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state().equals(IdleState.WRITER_IDLE)) {
                System.out.println("服务器还活着么？");
                //发送心跳包
                ctx.writeAndFlush(HEARTBEAT_SEQUENCE.duplicate());
            }
        }
    }
}
